#lang scribble/base

@(require "shared.rkt")

@;@title[#:tag "correct-maintain-speed"]{Basic Facts of Life}
@title[#:tag "correct-maintain-speed"]{最基本的常识}

@nested[#:style 'inset]{ @italic{Favor readers over writers.}
 --- Yaron Minsky, JaneStreet, 2010 at NEU/CCS}

@margin-note*{@;{This ordering is occasionally wrong. For example, we could
 avoid IEEE floating point numbers nearly all of the time. To make this
 precise, the Racket @scheme[sqrt] function could return a rational number
 close to the IEEE float result.  We don't do such silly things, however,
 because we have decided to value speed over precision in this context.}这个顺序有时是错误的。例如，我们几乎可以一直避免使用IEEE浮点数。为了精确起见，Racket@scheme[sqrt]函数可以返回一个接近IEEE浮点结果的有理数。然而，我们不会做这种愚蠢的事情，因为在这种情况下，我们确定要重视速度而不是精度。}
@;{Strive to write code that is correct; maintainable; and fast. The ordering
 of these adjectives is critical: correct is more important than
 maintainable; maintainable is more important than fast; and fast is
 important to include, because nobody wants to live with slow programs.}
努力写出正确的、可维护的、快速的代码。这些形容词的顺序是至关重要的：正确比可维护更重要；可维护比快速更重要；包括快速也很重要，因为没有人愿意使用慢程序。

@;{This section explains these three points as far as the Racket code base is
 concerned. The rest of this guide is to spell out suggestions that should
 help you make correct, maintainable, and fast contributions to the Racket
 code base.}
本节就Racket代码库解释这三点。本指南的其余部分将详细说明一些建议，这些建议将帮助你对Racket代码库做出正确、可维护和快速的贡献。

@; -----------------------------------------------------------------------------
@section[#:tag "correctness"]{@;{Correctness and Testing}正确性和测试}

@;{@nested[#:style 'inset]{@italic{I have bug reports, therefore I exist.} -- Matthias,
watching Matthew, Robby, Shriram and others create the original code base}}
@nested[#:style 'inset]{@italic{我有bug报告，因此我存在。}——Matthias，看着Matthew、Robby、Shriram和其他人创建原始代码库}

@;{@nested[#:style 'inset]{@italic{It is the way we choose to fight our bugs that
 determines our character, not their presence or absence.} -- Robby, in response}}
@nested[#:style 'inset]{@italic{决定角色的是我们选择与错误抗争的方式，而不是它们的存在与否。}——Robby，作为回应}

@;{PLT aims to release good code and to eliminate mistakes as quickly as
 possible.  All software has mistakes; complete correctness is a
 perfectionist goal.  If mistakes are unknown, the software isn't being
 used. The goal is, however, to ensure some basic level of correctness
 before a feature is released and to ensure that the same mistake isn't
 introduced again.}
PLT的目标是发布好的代码并尽快消除错误。所有软件都有错误；完全正确是完美主义的目标。如果错误未知，则不使用该软件。然而，目标是在特性发布之前确保一些基本的正确性，并确保不再引入相同的错误。

@;{We ensure this basic level of correctness with large test suites. Our test
 suites contain tests at all levels. In addition to unit tests, you will
 find test suites that use a ``random testing'' strategy and tools, others
 use fuzz testing, yet others are end-to-end ``systems level'' tests, and
 DrRacket comes with an automatic GUI player that explores its
 functionality.}
我们使用大型测试套件来确保这种基本的正确性。我们的测试套件包含所有级别的测试。除了单元测试之外，你还可以找到使用“随机测试”策略和工具的测试套件，另外的测试套件使用模糊测试，而其他测试套件则是端到端的“系统级”测试，DrRacket还附带了一个自动的GUI播放器，可以探索其功能。

@;{For details on testing in the context of the Racket code base, see
 @secref{testing}.}
有关在Racket原始代码上下文中进行测试的详细信息，请参见@secref{testing}。

@; -----------------------------------------------------------------------------
@;{@section{Maintenance}}
@section{维护}

@;{If we wish to create maintainable code, we must ensure that our code is
 comprehensible. Code is comprehensible when you can understand its
 external purpose; when you can guess from its external purpose at its
 organization; when the organization and the code live up to consistent
 criteria of style; and when the occasional complex part comes with
 internal documentation.}
如果我们想要创建可维护的代码，我们必须确保我们的代码是可理解的。当你能理解代码的外在目的时，当你能从它在组织中的外在目的中猜出时，当组织和代码符合一致的风格标准时，当偶尔复杂的部分带有内部文档时，代码是可以理解的。

@;{Released code must have documentation. Conversely a change to the external
 behavior of code must induce a simultaneous change to its documentation.
 Here ``simultaneous'' means that the two changes are in the same 'push'
 to the code base, not necessarily in the same 'commit'. Also see
 @secref{branch-and-commit} for more on Git actions.}
发布的代码必须有文档。相反，对代码外部行为的更改必须导致对其文档的同时更改。这里的“同时”意味着这两个更改在对代码基的同一个“推送”中，而不一定在同一个“提交”中。有关Git操作的更多信息，请参见@secref{branch-and-commit}。

@;{For style rules on documenting code, refer to the}
有关记录代码的样式规则，请参阅
 @;{@hyperlink["http://docs.racket-lang.org/scribble/how-to-doc.html#%28part._reference-style%29"]{style
 guide in the Scribble manual}.  Ideally documentation comes in two parts,
 possibly located in the same document: a ``Guide'' section, which explains
 the purpose and suggests use cases, and a traditional ``Reference''
 section, which presents the minutiae. The documentation for HtDP/2e
 teachpacks is an example where the two parts are collocated. Also consider
 adding examples for each function and construct in your ``Reference''
 section.  Finally, ensure you have all the correct @tt{for-label}
 @tt{require}s and make use of other useful cross-references.}
@hyperlink["http://docs.racket-lang.org/scribble/how-to-doc.html#%28part._reference-style%29"]{scribble手册的样式指南}。理想情况下，文档分为两部分，可能位于同一文档中：一个“指南”部分（解释目的并建议用例）和一个传统的“参考”部分（表示细节）。HtDP/2e教学包的文档就是一个将这两个部分放在一起的示例。还要考虑在“参考”部分为每个函数和构造添加示例。最后，确保你拥有所有正确的@tt{for-label}  @tt{require}并使用其他有用的交叉引用。

@;{Having said that, the production of a system like Racket occasionally
 requires experimentation. Once we understand these new pieces of
 functionality, though, it is imperative to discard the ``failure
 branches'' of an experiment and to turn the successful part into a
 maintainable package.  You may even consider converting your code to Typed
 Racket eventually.}
尽管如此，像Racket这样的系统的生产偶尔需要尝试。然而，一旦我们理解了这些新的功能，就必须放弃尝试中的“失败分支”，并将成功的部分转换为可维护的包。你甚至可以考虑最终将代码转换为Typed Racket。

@;{Without adherence to basic elements of style, code comprehension becomes
 impossible. The rest of this document is mostly about these elements of
 style, including some suggestions on minimal internal documentation.}
如果不坚持风格的基本元素，代码理解就变得不可能。本文的其余部分主要是关于这些样式元素的，包括一些关于最小内部文档的建议。

@; -----------------------------------------------------------------------------
@;{@section{Speed}}
@section{速度}

@;{Making code fast is an endless task. Making code @emph{reasonably fast} is the goal.}
快速编写代码是一项无止境的任务。使代码@emph{相当快}是目标。

@;{As with correctness, performance demands some ``testing.'' At a minimum,
 exercise your code on some reasonably realistic inputs and some larger
 ones. Add a file to the test suite that runs large inputs regularly. For
 example, a regular test suite for a Universe display deals with a 50 x 50
 display window; one of its stress tests checks whether Universe event
 handlers and drawing routines can cope with laptop size displays or even a
 30in display. Or, if you were to write a library for a queue data
 structure, a regular test suite ensures that it deals correctly with
 enqueue and dequeue for small queues, including empty ones; a stress test
 suite for the same library would run the queue operations on a variety of
 queue sizes, including very large queues of say tens of thousands
 elements.}
与正确性一样，性能要求一些“测试”。至少，在一些相当实际的输入和一些较大的输入上练习代码。将文件添加到定期运行大型输入的测试套件中。例如，Universe显示的常规测试套件处理50 x 50的显示窗口；其中一个压力测试检查Universe事件处理程序和绘图例程是否可以处理笔记本大小的显示，甚至30英寸的显示。或者，如果要为队列数据结构编写库，常规测试套件可以确保它正确处理小队列（包括空队列）的排队和出列问题；同一个库的压力测试套件可以在各种队列大小上运行队列操作，包括非常大的队列（比如上万个元素）。

@;{Stress tests don't normally have an expected output, so they never
 pass. The practice of writing stress tests exposes implementation flaws or
 provides comparative data to be used when choosing between two APIs. Just
 writing them and keeping them around reminds us that things can go bad and
 we can detect when performance degrades through some other door. Most
 importantly, a stress test may reveal that your code isn't implementing an
 algorithm with the expected @math{O(.)} running time. Finding out that
 much alone is useful. If you can't think of an improvement, just document
 the weakness in the external library and move on.}
压力测试通常没有预期的结果，所以它们永远不会通过。编写压力测试的实践暴露了实现缺陷，或者在选择两个API时提供了要使用的比较数据。只要把它们写下来并放在身边，就会提醒我们，事情可能会变得糟糕，我们可以通过另一扇门检测到性能何时下降。最重要的是，压力测试可能会显示代码没有实现具有预期@math{O(.)}运行时间的算法。光是找出这么多是有用的。如果你想不出改进的地方，只需记录下外部库中的弱点，然后继续前进。

@;{And as you read on, keep in mind that we are not perfectionists. We produce
 reasonable software.}
当你继续阅读时，请记住我们不是完美主义者。我们生产合理的软件。
